package data.mysql;

import java.sql.Connection;
import java.sql.SQLException;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;

import common.Logger;

import data.DaoFactory;
import data.IDao;
import data.bean.DataBean;
import data.exception.DaoException;

/**
 * Dao factory for MySQL database.
 * 
 * @author chuxiaoyuan
 */
public final class MySQLDaoFactory extends DaoFactory {

	/**
	 * Constructor.
	 */
	public MySQLDaoFactory() {
		// Nothing
	}
	
	/**
	 * The logger.
	 */
	protected static final Logger logger = new Logger(MySQLDaoFactory.class);
	
	static {
		
		String dsName = "java:comp/env/jdbc/onlinepurchase";
		Context ctx;
		try {
			// Initialize data source.
			ctx = new InitialContext();
			DS=(DataSource)ctx.lookup(dsName);
			
		} catch (NamingException  e) {
		
			logger.error(
					"Failed to initialize database connection information: " + dsName, 
					e);
			throw new ExceptionInInitializerError(e);
		}
	}
	
	/**
	 * Data source.
	 */
	protected static DataSource DS;

	/*
	 * (non-Javadoc)
	 * 
	 * @see data.DaoFactory#getConnection()
	 */
	@Override
	public Connection getConnection() throws DaoException {
		
		// Open a new connection.
		return MySQLDaoFactory.openConnection();
	}
	
	/**
	 * Open database connection
	 */
	public static Connection openConnection() throws DaoException {
		
		try {
			// Get a new connection
			
			Connection conn = DS.getConnection();
			logger.debug("New connection created.");
			return conn;
			
		} catch (SQLException e) {
			
			String msg = "Failed to open connection!";
			logger.error(msg, e);
			throw new DaoException(msg, e);
		}
	}

	/**
	 *  Create the DAO instance.
	 */
	@SuppressWarnings("unchecked")
	@Override
	public <T extends IDao<? extends DataBean>> T getDao(DaoName daoName) {	
		
		IDao<?> dao = null;
		 
		switch (daoName) {
		case UserDao:
			dao = new UserDao();
			break;
			
		case ProductprofileDao:
			dao = new ProductprofileDao();
			break;
			
		case ProductDao:
			dao = new ProductDao();
			break;
			
		case OrderDao:
			dao = new OrderDao();
			break;
			
		case MenuitemDao:
			dao = new MenuitemDao();
			break;
			
		case CustomerDao:
			dao = new CustomerDao();
			break;
			
		case CompositionDao:
			dao = new CompositionDao();
			break;
			
		case ComponentDao:
			dao = new ComponentDao();
			break;
			
		}
		
		return (T)dao;
	}

}
